package com.tomshushu.doc.freedoc.modular.version.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tomshushu.doc.freedoc.core.exception.ServiceException;
import com.tomshushu.doc.freedoc.core.factory.PageFactory;
import com.tomshushu.doc.freedoc.core.model.result.PageResult;
import com.tomshushu.doc.freedoc.modular.doc.entity.DocEntity;
import com.tomshushu.doc.freedoc.modular.doc.service.DocService;
import com.tomshushu.doc.freedoc.modular.user.entity.UserEntity;
import com.tomshushu.doc.freedoc.modular.user.service.UserService;
import com.tomshushu.doc.freedoc.modular.version.entity.VersionEntity;
import com.tomshushu.doc.freedoc.modular.version.mapper.VersionMapper;
import com.tomshushu.doc.freedoc.modular.version.param.AddVersionParam;
import com.tomshushu.doc.freedoc.modular.version.param.PageVersionParam;
import com.tomshushu.doc.freedoc.modular.version.param.RebackVersionParam;
import com.tomshushu.doc.freedoc.modular.version.service.VersionService;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @description:
 * @author: zhouhong
 * @date: 2025-06-10 17:26
 * @version: 1.0
 */
@Service
public class VersionServiceImpl extends ServiceImpl<VersionMapper, VersionEntity> implements VersionService {
    @Resource
    private UserService userService;
    @Resource
    private DocService docService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addVersion(AddVersionParam param) {
        // 当前版本
        VersionEntity currentVersion = this.getOne(new LambdaQueryWrapper<VersionEntity>()
                .eq(VersionEntity::getDocId, param.getDocId())
                .eq(VersionEntity::getIsCurrent, true));

        // 原子操作版本
        AtomicInteger currentVersionNum = new AtomicInteger(currentVersion == null ? 0 : currentVersion.getVersionNum());

        if (ObjectUtil.isNotNull(currentVersion)) {
            if (!Objects.equals(currentVersion.getContentHash(), param.getContentHash())) {
                // 创建新建版本
                param.setVersionNum(currentVersionNum.getAndIncrement());
                createVersion(param);
                // 将之前的版本设置为非当前版本
                currentVersion.setIsCurrent(false);
                this.updateById(currentVersion);
            }
        } else {
            // 创建新建版本
            param.setVersionNum(currentVersionNum.get());
            createVersion(param);
        }
    }

    private void createVersion(AddVersionParam param) {
        String userId = StpUtil.getLoginIdAsString();
        VersionEntity version =  new VersionEntity();
        BeanUtils.copyProperties(param, version);
        version.setCreateUser(userId);
        version.setIsCurrent(true);
        version.setCreateTime(new Date());
        save(version);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void rebackVersion(RebackVersionParam param) {
        VersionEntity needVersion = getById(param.getVersionId());
        if (ObjectUtil.isNull(needVersion)) {
            throw new ServiceException("版本不存在");
        }
        // 当前版本
        VersionEntity currentVersion = this.getOne(new LambdaQueryWrapper<VersionEntity>()
                .eq(VersionEntity::getDocId, needVersion.getDocId())
                .eq(VersionEntity::getIsCurrent, true));

        DocEntity doc = docService.getById(needVersion.getDocId());
        // 将需要回滚的版本设置为当前版本
        needVersion.setIsCurrent(true);
        this.updateById(needVersion);
        // 更新文档为需要回滚的文档
        doc.setDocContent(needVersion.getDocContent());
        docService.updateById(doc);

        // 将当前版本设置为非当前版本
        currentVersion.setIsCurrent(false);
        this.updateById(currentVersion);
        // 删除版本大于需要设置版本的数据
        this.remove(new LambdaQueryWrapper<VersionEntity>()
                .eq(VersionEntity::getDocId, needVersion.getDocId())
                .gt(VersionEntity::getCreateTime, needVersion.getCreateTime()));
    }

    @Override
    public PageResult<VersionEntity>  pageVersion(PageVersionParam param) {
        LambdaQueryWrapper<VersionEntity> queryWrapper = new LambdaQueryWrapper<>();
        if (ObjectUtil.isNotNull(param.getDocId())) {
            queryWrapper.eq(VersionEntity::getDocId, param.getDocId());
        }
        queryWrapper.orderByDesc(VersionEntity::getIsCurrent ,VersionEntity::getCreateTime);
        Page<VersionEntity> page = this.page(PageFactory.defaultPage(), queryWrapper);
        page.getRecords().forEach(item -> {
            UserEntity user = userService.getById(item.getCreateUser());
            item.setCreateUser(user.getUserName());
        });
        return new PageResult<>(page);
    }
}